#pragma once
#include <list>
#include <map>
#include <mutex>
#include <unordered_map>
#include "ArcNode.h"

namespace Cache
{
template<typename K, typename V>
class LruPart
{
public:
    using NodeType = ArcNode<K, V>;
    using NodePtr = std::shared_ptr<NodeType>;
    using NodeMap = std::unordered_map<K, NodePtr>;

private:
    size_t _changeFlag;
    std::mutex _mutex;

    NodeMap _mainCaches;
    NodePtr _mainHead;
    NodePtr _mainTail;
    size_t _mainCapacity;

    NodeMap _ghostCaches;
    NodePtr _ghostHead;
    NodePtr _ghostTail;
    size_t _ghostCapacity;

public:
    explicit LruPart(size_t size, size_t changeFlag)
        :_mainCapacity(size),
         _ghostCapacity(size),
         _changeFlag(changeFlag)
    {
        initializeLists();
    }

    bool put(K key,V value)
    {
        if(_mainCapacity == 0) return false;

        std::lock_guard<std::mutex> lock(_mutex);
        auto it = _mainCaches.find(key);
        if(it != _mainCaches.end())
        {
            return updateExistingNode(it->second, value);//刷新已存在的节点
        }
        return addNewNode(key, value);//添加新节点
    }

    bool get(K key, V& value,bool & shouldChangeFlag)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        auto it = _mainCaches.find(key);
        if(it != _mainCaches.end())
        {
            shouldChangeFlag = updateNodeAccess(it->second);
            value = it->second->getValue();
            return true;
        }
        return false;
    }

    bool checkGhost(K key)
    {
        auto it = _ghostCaches.find(key);
        if (it != _ghostCaches.end())
        {
            removeFromGhost(it->second);
            _ghostCaches.erase(it);
            return true;
        }
        return false;
    }


    void increaseCapacity() { ++_mainCapacity; }

    bool decreaseCapacity()
    {
        if (_mainCapacity <= 0) return false;
        if (_mainCaches.size() == _mainCapacity)
        {
            evictLeastRecent();//驱逐最近最少访问
        }
        --_mainCapacity ;
        return true;
    }
private:
    void initializeLists()
    {
        _mainHead = std::make_shared<NodeType>();
        _mainTail = std::make_shared<NodeType>();
        _mainHead->_next = _mainTail;
        _mainTail->_prev = _mainHead;

        _ghostHead = std::make_shared<NodeType>();
        _ghostTail = std::make_shared<NodeType>();
        _ghostHead->_next = _ghostTail;
        _ghostTail->_prev = _ghostHead;
    }

    bool updateExistingNode(NodePtr node, const V& value)
    {
        node->setValue(value);
        moveToFront(node);
        return true;
    }

    bool addNewNode(const K& key, const V& value)
    {
        if(_mainCaches.size() >= _mainCapacity )//
        {
            evictLeastRecent();//驱逐最近最少访问
        }
        NodePtr newNode = std::make_shared<NodeType>( key,value);
        _mainCaches[key] = newNode;//哈希表中添加
        addToFront(newNode);//链表中添加（添加到头部）
        return true;
    }

    bool updateNodeAccess(NodePtr node)
    {
        moveToFront(node);
        node->inAccessCount();
        return node->getAccessCount() >= _changeFlag;
    }

    void moveToFront(NodePtr node)
    {
        //直接删掉
        if( !node->_prev.expired() && node->_next)
        {
            auto prev = node->_prev.lock();
            prev->_next = node->_next;
            node->_next->_prev = node->_prev;
            node->_next = nullptr;
        }
        //添加节点
        addToFront(node);
    }

    void evictLeastRecent()
    {
        NodePtr leastRecent = _mainTail->_prev.lock();
        if(!leastRecent || leastRecent == _mainHead)
        {
            return;
        }
        //从主链表中删除
        removeFromMain(leastRecent);

        //添加到ghost缓存中去
        if(_ghostCaches.size() >= _ghostCapacity)
        {
            removeOldestGhost();
        }
        addToGhost(leastRecent);

        //从主缓存的哈希表中删除
        _mainCaches.erase(leastRecent->getKey());
    }
    void addToFront(NodePtr node)
    {
        node ->_next = _mainHead->_next;
        node->_prev = _mainHead;
        _mainHead->_next->_prev = node;
        _mainHead->_next = node;
    }

    void removeFromMain(NodePtr node)
    {
        if (!node->_prev.expired() && node->_next) {
            auto prev = node->_prev.lock();
            prev->_next = node->_next;
            node->_next->_prev = node->_prev;
            node->_next = nullptr; // 清空指针，防止悬垂引用
        }
    }

    void removeOldestGhost()
    {
        // 使用lock()方法，并添加null检查
        NodePtr oldestGhost = _ghostTail->_prev.lock();
        if (!oldestGhost || oldestGhost == _ghostHead)
            return;

        removeFromGhost(oldestGhost);
        _ghostCaches.erase(oldestGhost->getKey());
    }

    void removeFromGhost(NodePtr node)
    {
        if (!node->_prev.expired() && node->_next) {
            auto prev = node->_prev.lock();
            prev->_next = node->_next;
            node->_next->_prev = node->_prev;
            node->_next = nullptr; // 清空指针，防止悬垂引用
        }
    }

    void addToGhost(NodePtr node)
    {
        // 重置节点的访问计数
        node->_accessCount = 1;

        // 添加到幽灵缓存的头部
        node->_next = _ghostHead->_next;
        node->_prev = _ghostHead;
        _ghostHead->_next->_prev = node;
        _ghostHead->_next = node;

        // 添加到幽灵缓存映射
        _ghostCaches[node->getKey()] = node;
    }
};
}

